using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
using Services;
using WAS.Logic.SampleLevel;
using Utilities.Menu.UIElements;
using WAS.Resources;

namespace WAS.Menu
{

    using Game = Microsoft.Xna.Framework.Game;

    public class DefeatScreen : Microsoft.Xna.Framework.DrawableGameComponent
    {
        SpriteBatch sprite_batch;
        Matrix screen_transform;
        Texture2D bg, box_body, bwd;
        SpriteFont title_font, text_font, menu_font;
        Button back_to_menu, save_scores, confirm_save;
        SoundEffect click;
        InputManager input_manager;

        VirtualKeyboard keyboard;
        TextEdit text_edit;

        BaseLevelStats user_data;

        bool initialized = false, increase_a = false, save_state = false;
        float alpha = 0.0f, wait_to_tap = 0.5f;
        //private Texture2D up_l_box;
        //private Texture2D lo_l_box;
        //private Texture2D up_r_box;
        //private Texture2D lo_r_box;

        public DefeatScreen(Game game, BaseLevelStats user_data)
            : base(game)
        {
            game.Components.Add(new InputManager(game));
            
            this.user_data = user_data;
        }
        AudioManager audio_manager;
        ContentManager Content { get { return Game.Content; } }
        public override void Initialize()
        {
            input_manager = Game.Services.GetService(typeof(IInputManager)) as InputManager;
            input_manager.OnTap += new InputManager.Tap(on_tap);
            base.Initialize();
        }

        protected override void LoadContent()
        {
            audio_manager = Game.Services.GetService(typeof(IAudioManager)) as AudioManager;
            sprite_batch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH, GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);
            bg = Content.Load<Texture2D>("LevelFinished/defeat_bg_png");
            bwd = Content.Load<Texture2D>("Menu/button_rwd");
            title_font = Content.Load<SpriteFont>("Fonts/OCRAExtended32");
            text_font = Content.Load<SpriteFont>("Fonts/OCRAExtended18");
            menu_font = Content.Load<SpriteFont>("Fonts/OCRAExtended24");
            //up_l_box = Content.Load<Texture2D>("LevelFinished/hor_left");
            //lo_l_box = Content.Load<Texture2D>("LevelFinished/ver_left");
            //up_r_box = Content.Load<Texture2D>("LevelFinished/hor_right");
            //lo_r_box = Content.Load<Texture2D>("LevelFinished/ver_right");
            box_body = Content.Load<Texture2D>("LevelFinished/victory_bg");
            click = Game.Content.Load<SoundEffect>("Audio/button");

            back_to_menu = new Button
            {
                CollisionBox = new Rectangle(10,
                    GraphicsDevice.Viewport.Height / 2 - bwd.Height / 2, bwd.Width, bwd.Height),
                Label = Strings.Quit,
                Position = Vector2.Zero
            };
            var sm = menu_font.MeasureString(Strings.SaveScore); var x = Game.GraphicsDevice.Viewport.Width / 2.0f - sm.X / 2.0f;
            save_scores = new Button
            {
                CollisionBox = new Rectangle((int)x - 10, 415, (int)sm.X + 20, (int)sm.Y + 20),
                Label = Strings.SaveScore,
                Position = new Vector2(x, 425)
            };
            sm = menu_font.MeasureString(Strings.Confirm); x = Game.GraphicsDevice.Viewport.Width / 2.0f - sm.X / 2.0f;
            confirm_save = new Button
            {
                CollisionBox = new Rectangle((int)x - 10, 415, (int)sm.X + 20, (int)sm.Y + 20),
                Label = Strings.Confirm,
                Position = new Vector2(x, 425)
            };

            text_edit = new TextEdit(text_font, Content.Load<Texture2D>("Menu/text_edit_bg"),
                new Vector2(GraphicsDevice.Viewport.Width / 2.0f - Content.Load<Texture2D>("Menu/text_edit_bg").Width / 2.0f, 80), 8);

            //keyboard = new VirtualKeyboard(text_edit, text_font, Content.Load<SoundEffect>("Audio/keyboard_click"),
            //    Content.Load<Texture2D>("Menu/keyboard_bg"), Content.Load<Texture2D>("Menu/key_bg"),
            //    Content.Load<Texture2D>("Menu/key_delete"), 200, 150);

            //Richiamato il costruttore con l'ultimo parametro booleano "true" per la tastiera qwerty, ed il "qwerty_keyboard_bg"
            keyboard = new VirtualKeyboard(text_edit, text_font, Content.Load<SoundEffect>("Audio/keyboard_click"),
                Content.Load<Texture2D>("Menu/keyboard_qwerty_bg"), Content.Load<Texture2D>("Menu/key_bg"),
                Content.Load<Texture2D>("Menu/key_delete"), 200, 150, true);
            
            base.LoadContent();
        }

        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(IInputManager));

            base.Dispose(disposing);
        }

        void on_tap(Vector2 tap_position)
        {
            if (wait_to_tap <= 0.0f)
            {
                var p = tap_position.ToPoint(screen_transform);

                if (save_state)
                {
                    keyboard.Update(tap_position);

                    if (confirm_save.CollisionBox.Contains(p) && text_edit.Text.Length > 1)
                    {
                        click.Play(AudioManager.Volume, 0.0f, 0.0f);
                        var n = text_edit.Text.ToString();
                        Leaderboard.AddScore(new LeaderboardEntry()
                        {
                            Score = user_data.LevelScore,
                            Name = n,
                            Date = DateTime.Now.ToString().Split(' ')[0]
                        });
                        StateManager.SelectMenu(Game);
                    }
                }

                if (back_to_menu.CollisionBox.Contains(p) || input_manager.IsBackButtonPressed())
                {
                    
                    StateManager.SelectMenu(Game);
                    
                    click.Play(AudioManager.Volume, 0.0f, 0.0f);
                }
                else
                    if (save_scores.CollisionBox.Contains(p) && !save_state)
                    {
                        save_state = true;
                        click.Play(AudioManager.Volume, 0.0f, 0.0f);
                    }
            }
        }

        public override void Update(GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            wait_to_tap -= dt;

            if (!initialized)
            {
                alpha = MathHelper.Clamp(alpha + dt * 2.0f, 0.0f, 1.0f);
                if (alpha == 1.0f)
                {
                    initialized = true;
                }
            }

            if (save_state)
            {
                if (!increase_a)
                {
                    alpha = MathHelper.Clamp(alpha - dt * 2.0f, 0.0f, 1.0f);
                    if (alpha == 0.0f)
                        increase_a = true;
                }
                else
                    alpha = MathHelper.Clamp(alpha + dt, 0.0f, 1.0f);
            }

            base.Update(gameTime);
        }

        Rectangle box_rect = new Rectangle(35, 150, 410, 335);
        public override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

            sprite_batch.Draw(bg, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);

            if (!save_state || !increase_a)
            {
                sprite_batch.Draw(box_body, new Rectangle((int)(GraphicsDevice.Viewport.Width / 2.0f - box_body.Width / 2.0f),
                20, box_body.Width, 380), Color.White * alpha);
                sprite_batch.DrawString(title_font, Strings.Defeat, new Vector2(CenterValue(Game.GraphicsDevice.Viewport.Width,
                    title_font.MeasureString(Strings.Defeat).X), 120), Color.White * alpha);
                sprite_batch.DrawString(text_font, Strings.TotalScore + user_data.LevelScore,
                    new Vector2(Game.GraphicsDevice.Viewport.Width / 2.0f -
                    text_font.MeasureString(Strings.TotalScore + user_data.LevelScore).X / 2.0f, 260), Color.White * alpha);

                sprite_batch.DrawString(menu_font, save_scores.Label, save_scores.Position + Vector2.One * 2.0f, Color.Black * alpha);
                sprite_batch.DrawString(menu_font, save_scores.Label, save_scores.Position, Color.White * alpha);
            }
            else
            {
                keyboard.DrawKeyboard(gameTime, sprite_batch, alpha);

                sprite_batch.DrawString(menu_font, confirm_save.Label, confirm_save.Position + Vector2.One * 2.0f, Color.Black * (text_edit.Text.Length > 1 ? alpha : Math.Min(0.5f, alpha)));
                sprite_batch.DrawString(menu_font, confirm_save.Label, confirm_save.Position, Color.White * (text_edit.Text.Length > 1 ? alpha : Math.Min(0.5f, alpha)));
            }

            sprite_batch.Draw(bwd, back_to_menu.CollisionBox, Color.White * alpha);

            sprite_batch.End();

            base.Draw(gameTime);
        }

        private float CenterValue(float screen_dim, float item_width)
        {
            return screen_dim / 2.0f - item_width / 2.0f;
        }
    }
}